# !/usr/bin/python3
# -*- coding: utf-8 -*-
# @Time    : 2021/10/8 14:11
# @Author  : zuodengbo
# @Email   : zuodb@amoydx.com
# @File    : decorator
# @Software: PyCharm
import jwt
from functools import wraps

from sanic import json
from sanic.log import logger

from user.function import check_uri
from utils.const import RespCode


def check_token(request):
    """
    校验token    
    :param request: 
    :return: 
    """
    try:
        data = jwt.decode(request.headers.get("access_token"),
                          request.app.config.FORWARDED_SECRET, algorithms=["HS256"])
    except jwt.exceptions.ExpiredSignatureError as e:
        logger.error("Token has expired: {}".format(e))
        return False, e.__str__()
    except jwt.exceptions.InvalidTokenError as e:
        logger.error("Invalid token error: {}".format(e))
        return False, e.__str__()
    else:
        return True, data


def login_required(wrapped):
    """
    token校验装饰器
    :param wrapped:
    :return:
    """

    def inner(func):
        @wraps(func)
        async def decorated_func(request, *args, **kwargs):
            is_login, msg = check_token(request)
            if is_login:
                user_id = msg["user_id"]
                uri = request.path
                is_allowed, perm_msg = await check_uri(uri, user_id)
                if is_allowed:
                    resp = func(request, *args, **kwargs)
                    return await resp
                else:
                    data = {"code": RespCode.FORBIDDEN, "message": perm_msg}
                    return json(data)
            else:
                data = {"code": RespCode.REQUIRE_LOGIN, "message": msg}
                return json(data)

        return decorated_func

    return inner(wrapped)
